#include <xpp/net/TcpSocket.h>
#include <xpp/net/Tcp4Address.h>
#include <xpp/net/Tcp6Address.h>

using namespace xpp;
using namespace xpp::net;

extern "C" { int xp_main (); }

int xp_main ()
{
	if (Socket::startup() == -1) {
		xp_printf (XP_TEXT("can not initialize the socket subsystem\n"));
		return -1;
	}

	try {
		//InetAddress target (XP_TEXT("http"), XP_TEXT("localhost"), InetAddress::V6);
		//InetAddress target (XP_TEXT("ssh"), XP_TEXT("localhost"), InetAddress::V6);
		//InetAddress target (XP_TEXT("ssh"), XP_TEXT("bacon"), InetAddress::V6);
		Tcp4Address target (XP_TEXT("ssh"), XP_TEXT("localhost"));
		//InetAddress target (XP_TEXT("ssh"), XP_TEXT("localhost"), InetAddress::V4);

		TcpSocket socket;
		xp_byte_t buf[1000];

		for (int i = 0; i < 10; i++) {
			socket.enableTimeout (3000);

			Socket::Handle handle = ::socket (PF_INET, SOCK_STREAM, 0);
			if (handle == Socket::INVALID_HANDLE) {
				printf ("can't create socket\n");
				Socket::cleanup ();
				return -1;
			}

			if (socket.open (handle, target) == -1) {
				xp_printf (
					XP_TEXT("ERROR: can't open - %d\n"), socket.errorCode());
				Socket::cleanup ();
				return -1;
			}

			if (socket.connect () == -1) {
				xp_printf (
					XP_TEXT("ERROR: can't connect - %d\n"), socket.errorCode());
				Socket::cleanup ();
				return -1;
			}

			for (;;)  {
				xp_ssize_t n = socket.receive (buf, xp_sizeof(buf) - 1);
				if (n == -1 ) {
					xp_printf (
						XP_TEXT("receive error - %d\n"), socket.errorCode());
					break;
				}
				if (n == 0) break;
				buf[n] = '\0';
				printf ("%d [%s]", i, buf);
			}

			socket.close ();
		}

	}
	catch (Exception& ex) {
		xp_printf (XP_TEXT("exception: %s, %s\n"), 
			XPP_EXCEPTION_NAME(ex), XPP_EXCEPTION_MSG(ex));
	}

	Socket::cleanup ();
	return 0;
}
